/**
 * 
 */
package com.googlecode.easyibatis.core.utils;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.LogFactory;


import com.google.common.collect.Lists;
import com.googlecode.easyibatis.core.exception.EasyIbatisException;
import com.googlecode.easyibatis.core.model.Model;
import com.googlecode.easyibatis.core.model.annotation.ManyToOne;

/**
 * @author zxq
 * 
 */
public class FilterUtils {
	protected final static org.apache.commons.logging.Log logger = LogFactory.getLog(FilterUtils.class);
	/**
	 * 
	 * @param equalsFilter
	 * @param likeFilter
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Model> Map handleEqualsFilterAndLikeFilter(Class<T> modelClass,
			Map<String, ?> equalsFilter, Map<String, ?> likeFilter) throws EasyIbatisException {
		try {
			Map param = ModelLoader.loadSelectModel(modelClass);
			// 处理等于
			Pattern pattern = Pattern.compile("(.+)\\.(.+)");
			List<EqualsFilterHandler> equalsFilterHandlers = Lists.newArrayList();
			if (equalsFilter != null && equalsFilter.size() > 0) {
				for (Entry<String, ?> entry : equalsFilter.entrySet()) {
					String key = entry.getKey();
					Object value = entry.getValue();
					Matcher matcher = pattern.matcher(key);
					if (matcher.find()) {
						String fieldName = matcher.group(1);
						try {
							Field field = modelClass.getDeclaredField(fieldName);
							ManyToOne manyToOne = field.getAnnotation(ManyToOne.class);
							if (manyToOne != null && StringUtils.isNotBlank(manyToOne.columnName())) {
								List<ManyToOneHandler> manyToOneHandlers = (List<ManyToOneHandler>) param
										.get("manyToOneHandlers");
								for (ManyToOneHandler manyToOneHandler : manyToOneHandlers) {
									if (StringUtils.equals(manyToOneHandler.getColumnName(), manyToOne.columnName())) {
										equalsFilterHandlers.add(new EqualsFilterHandler(manyToOne.columnName(), value,
												matcher.group(2), manyToOneHandler.getAliasTableName()));
									}
								}
							}
						} catch (Exception e) {
							if (logger.isErrorEnabled()) {
								logger.error(String.format("无法获取%s属性", fieldName), e);
							}
						}
					} else {
						equalsFilterHandlers.add(new EqualsFilterHandler(key, value, key, "t"));
					}
				}
			}
			// 处理like
			List<LikeFilterHangdler> likeFilterHandlers = Lists.newArrayList();
			if (likeFilter != null && likeFilter.size() > 0) {
				for (Entry<String, ?> entry : likeFilter.entrySet()) {
					String key = entry.getKey();
					Object value = entry.getValue();
					Matcher matcher = pattern.matcher(key);
					if (matcher.find()) {
						String fieldName = matcher.group(1);
						try {
							Field field = modelClass.getDeclaredField(fieldName);
							ManyToOne manyToOne = field.getAnnotation(ManyToOne.class);
							if (manyToOne != null && StringUtils.isNotBlank(manyToOne.columnName())) {
								List<ManyToOneHandler> manyToOneHandlers = (List<ManyToOneHandler>) param
										.get("manyToOneHandlers");
								for (ManyToOneHandler manyToOneHandler : manyToOneHandlers) {
									if (StringUtils.equals(manyToOneHandler.getColumnName(), manyToOne.columnName())) {
										likeFilterHandlers.add(new LikeFilterHangdler(manyToOne.columnName(), value,
												matcher.group(2), manyToOneHandler.getAliasTableName()));
									}
								}
							}
						} catch (Exception e) {
							if (logger.isErrorEnabled()) {
								logger.error(String.format("无法获取%s属性", fieldName), e);
							}
						}
					} else {
						likeFilterHandlers.add(new LikeFilterHangdler(key, value, key, "t"));
					}
				}
			}
			param.put("equalsFilterHandlers", equalsFilterHandlers);
			param.put("likeFilterHandlers", likeFilterHandlers);
			return param;
		} catch (Exception e) {
			if (logger.isErrorEnabled()) {
				logger.error(e.getMessage(), e);
			}
			throw new EasyIbatisException(e);
		}
	}
	/**
	 * 
	 * @param <T>
	 * @param modelClass
	 * @param equalsFilter
	 * @param likeFilter
	 * @param sorts
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Model> Map handleEqualsFilterAndLikeFilterAndSorts(Class<T> modelClass,
			Map<String, ?> equalsFilter, Map<String, ?> likeFilter, Sort... sorts) throws EasyIbatisException {
		try {
			Map param = ModelLoader.loadSelectModel(modelClass);
			// 处理等于
			Pattern pattern = Pattern.compile("(.+)\\.(.+)");
			List<EqualsFilterHandler> equalsFilterHandlers = Lists.newArrayList();
			if (equalsFilter != null && equalsFilter.size() > 0) {
				for (Entry<String, ?> entry : equalsFilter.entrySet()) {
					String key = entry.getKey();
					Object value = entry.getValue();
					Matcher matcher = pattern.matcher(key);
					if (matcher.find()) {
						String fieldName = matcher.group(1);
						try {
							Field field = modelClass.getDeclaredField(fieldName);
							ManyToOne manyToOne = field.getAnnotation(ManyToOne.class);
							if (manyToOne != null && StringUtils.isNotBlank(manyToOne.columnName())) {
								List<ManyToOneHandler> manyToOneHandlers = (List<ManyToOneHandler>) param
										.get("manyToOneHandlers");
								for (ManyToOneHandler manyToOneHandler : manyToOneHandlers) {
									if (StringUtils.equals(manyToOneHandler.getColumnName(), manyToOne.columnName())) {
										equalsFilterHandlers.add(new EqualsFilterHandler(manyToOne.columnName(), value,
												matcher.group(2), manyToOneHandler.getAliasTableName()));
									}
								}
							}
						} catch (Exception e) {
							if (logger.isErrorEnabled()) {
								logger.error(String.format("无法获取%s属性", fieldName), e);
							}
						}
					} else {
						equalsFilterHandlers.add(new EqualsFilterHandler(key, value, key, "t"));
					}
				}
			}
			// 处理like
			List<LikeFilterHangdler> likeFilterHandlers = Lists.newArrayList();
			if (likeFilter != null && likeFilter.size() > 0) {
				for (Entry<String, ?> entry : likeFilter.entrySet()) {
					String key = entry.getKey();
					Object value = entry.getValue();
					Matcher matcher = pattern.matcher(key);
					if (matcher.find()) {
						String fieldName = matcher.group(1);
						try {
							Field field = modelClass.getDeclaredField(fieldName);
							ManyToOne manyToOne = field.getAnnotation(ManyToOne.class);
							if (manyToOne != null && StringUtils.isNotBlank(manyToOne.columnName())) {
								List<ManyToOneHandler> manyToOneHandlers = (List<ManyToOneHandler>) param
										.get("manyToOneHandlers");
								for (ManyToOneHandler manyToOneHandler : manyToOneHandlers) {
									if (StringUtils.equals(manyToOneHandler.getColumnName(), manyToOne.columnName())) {
										likeFilterHandlers.add(new LikeFilterHangdler(manyToOne.columnName(), value,
												matcher.group(2), manyToOneHandler.getAliasTableName()));
									}
								}
							}
						} catch (Exception e) {
							if (logger.isErrorEnabled()) {
								logger.error(String.format("无法获取%s属性", fieldName), e);
							}
						}
					} else {
						likeFilterHandlers.add(new LikeFilterHangdler(key, value, key, "t"));
					}
				}
			}
			// 处理排序
			List<SortHandler> sortHandlers = Lists.newArrayList();
			if (ArrayUtils.isNotEmpty(sorts)) {
				for (Sort sort : sorts) {
					String propertyName = sort.getPropertyName();
					String sortType = sort.getSortType();
					Matcher matcher = pattern.matcher(propertyName);
					if (matcher.find()) {
						String fieldName = matcher.group(1);
						try {
							Field field = modelClass.getDeclaredField(fieldName);
							ManyToOne manyToOne = field.getAnnotation(ManyToOne.class);
							if (manyToOne != null && StringUtils.isNotBlank(manyToOne.columnName())) {
								List<ManyToOneHandler> manyToOneHandlers = (List<ManyToOneHandler>) param
										.get("manyToOneHandlers");
								for (ManyToOneHandler manyToOneHandler : manyToOneHandlers) {
									if (StringUtils.equals(manyToOneHandler.getColumnName(), manyToOne.columnName())) {
										sortHandlers.add(new SortHandler(manyToOne.columnName(), sortType, matcher
												.group(2), manyToOneHandler.getAliasTableName()));
									}
								}
							}
						} catch (Exception e) {
							if (logger.isErrorEnabled()) {
								logger.error(String.format("无法获取%s属性", fieldName), e);
							}
						}
					} else {
						sortHandlers.add(new SortHandler(propertyName, sortType, propertyName, "t"));
					}
				}
			}
			param.put("equalsFilterHandlers", equalsFilterHandlers);
			param.put("likeFilterHandlers", likeFilterHandlers);
			param.put("sortHandlers", sortHandlers);
			return param;
		} catch (Exception e) {
			if (logger.isErrorEnabled()) {
				logger.error(e.getMessage(), e);
			}
			throw new EasyIbatisException(e);
		}
	}
}
